#include "snetwork/Sock.h"
#include "snetwork/MasterProcess.h"

namespace Sock
{  
    int n_clientfd = -1;
    int n_fd_arr[MAX_FD_NUM];
    char* n_clientip_arr[MAX_FD_NUM];
    short int n_clientport_arr[MAX_FD_NUM];
    int n_fd_count = 0;//统计当前连接数
    int n_serverfd = -1;

#if defined(__GNUC__)    
    struct epoll_event n_ev, n_events[20];
    int n_epfd;
#endif

    std::string n_header;
    std::string n_response_header;
    std::string n_request_header;
    std::string n_response_body;
    
    vecStr n_rbArr;
    mapStrStr n_head_arr;
    mapStrStr n_fileinfo;
    mapStrStr n_textinfo;    
    mapStrStrIntStr n_FILES;
    
    int n_status = 200;//http status
    
    // cookies
	mapStrStr n_CookieSend;//response
	mapStrStr n_CookieRecv;//request
	mapStrStr n_Cookie;//save
    
    // set session
    mapStrStr n_Session;
    
    std::string n_clientip;

    CSock::CSock()
    {
        n_header.erase();
        n_fileinfo.clear();
        n_rbArr.clear();
        n_CookieSend.clear();
        n_CookieRecv.clear();
        n_Cookie.clear();
        n_Session.clear();
    }

    int CSock::nsock_init(unsigned int server_port)
    {
		
#if defined(_MSC_VER)
		WSADATA wsa;
		WSAStartup(MAKEWORD(2,2),&wsa);
#endif
        int ret;         
		struct sockaddr_in addr_remote;

		n_serverfd = socket(AF_INET, SOCK_STREAM, 0);

#if defined(_MSC_VER)
		const char * opt = "1";
        setsockopt(n_serverfd, SOL_SOCKET, SO_REUSEADDR, (const char*)opt, sizeof(opt)); //强制监听         
#elif defined(__GNUC__)
		//int opt = 1;
		//setsockopt(n_serverfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //强制监听        
        unsigned int        optval;
        struct linger        optval1;

        //设置SO_REUSEADDR选项(服务器快速重起)
        optval = 0x1;
        setsockopt(n_serverfd, SOL_SOCKET, SO_REUSEADDR, &optval, 4);
        
        //设置SO_LINGER选项(防范CLOSE_WAIT挂住所有套接字)
        optval1.l_onoff = 1;
        optval1.l_linger = 60;
        setsockopt(n_serverfd, SOL_SOCKET, SO_LINGER, &optval1, sizeof(struct linger));
#endif    
        
        addr_remote.sin_family = AF_INET;
        addr_remote.sin_port = htons(server_port);
        addr_remote.sin_addr.s_addr = INADDR_ANY;

#if defined(__GNUC__)
        bzero (&(addr_remote.sin_zero), 8);
#endif
        
        ret = bind(n_serverfd, (struct sockaddr*) &addr_remote, sizeof(struct sockaddr));
        if (ret < 0) {
            //throw CThrowException("bind ret<0");
            llog( "Error: bind ret<0!" ); 
        }
        else {
            llog( "bind ret>0 OK !" ); 
        }
        
		//std::cout << "n_serverfd=" <<  n_serverfd << std::endl;
        if (listen(n_serverfd, 30) < 0) {
            llog( "Error: listen fail!" ); 
            //throw CThrowException("listen fail");
        }


        return 0;
    }

    int CSock::nsock_setopt(int act, mapStrStr* param)
    {                                     
        m_param = param;
        return 0;
    }

    int CSock::nsock_exec(vecStr& ret)
    {
        CMasterProcess mp;
        
        mp.MasterProcessCycle();         
        return 0;
    }
     
    int CSock::nsock_close()
    {
#if defined(__GNUC__)
	    close(n_serverfd);
#endif

#if defined(_MSC_VER)
		closesocket(n_serverfd);
#endif
        return 0;
    }

}
